package auth;

import entity.UsersLocalHome;
import helper.SimpleJSONObject;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.ejb.CreateException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import transfer.Address;
import transfer.User;
import transfer.UserRole;

/**
 *
 * @author Oleh
 */
public class Registration extends HttpServlet {

    public static final String ok = "";
    public static final String wrong = "Incorrectly input!";
    public static final String exists = "Engaged!";
//    public static final String successMessage = "Customer registered";
//    public static final String errorMessage = "Error. Try again :)";
    public static final String loginParameter = "login";
    public static final String passwordParameter = "password";
    public static final String fNameParameter = "fName";
    public static final String lNameParameter = "lName";
    public static final String emailParameter = "email";
    public static final String countyParameter = "country";
    public static final String cityParameter = "city";
    public static final String streetParameter = "street";
    public static final String homeParameter = "home";
    public static final String appartmentParameter = "appartment";
    public static final String longitudeParameter = "longitude";
    public static final String latitudeParameter = "latitude";
//    public static final String successParameter = "success";
    public static final String loginPattern = "^[a-zA-Z]\\w{2,}$";
    public static final String passwordPattern = "\\w{6,14}$";
    public static final String fNamePattern = "^[a-zA-Z][a-zA-Z ,.'-]*$";
    public static final String lNamePattern = "^[a-zA-Z][a-zA-Z ,.'-]*$";
    public static final String emailPattern = "(([A-Za-z])|(\\d)|([-_.]))+@([A-Za-z])+[.]([A-Za-z]){2,4}";
    public static final String countryPattern = "^[a-zA-Z ,.'-]+$";
    public static final String cityPattern = "^[a-zA-Z ,.'-]+$";
    public static final String streetPattern = "^[a-zA-Z ,.'-]+$";
    public static final String homePattern = "^[a-zA-Z0-9 ,./'-]+$";

    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.err.println("Start registration");
        String login = request.getParameter(loginParameter);
        String password = request.getParameter(passwordParameter);
        String fName = request.getParameter(fNameParameter);
        String lName = request.getParameter(lNameParameter);
        String email = request.getParameter(emailParameter);
        String county = request.getParameter(countyParameter);
        String city = request.getParameter(cityParameter);
        String street = request.getParameter(streetParameter);
        String home = request.getParameter(homeParameter);
        String appartment = request.getParameter(appartmentParameter);
        String longitude = request.getParameter(longitudeParameter);
        String latitude = request.getParameter(latitudeParameter);

        boolean successValidate = true;
        SimpleJSONObject json = new SimpleJSONObject();

        if (validate(login, loginPattern)) {
            json.addProperty(loginParameter, ok);
        } else {
            json.addProperty(loginParameter, wrong);
            successValidate = false;
        }

        if (validate(password, passwordPattern)) {
            json.addProperty(passwordParameter, ok);
        } else {
            json.addProperty(passwordParameter, wrong);
            successValidate = false;
        }

        if (validate(fName, fNamePattern)) {
            json.addProperty(fNameParameter, ok);
        } else {
            json.addProperty(fNameParameter, wrong);
            successValidate = false;
        }

        if (validate(lName, lNamePattern)) {
            json.addProperty(lNameParameter, ok);
        } else {
            json.addProperty(lNameParameter, wrong);
            successValidate = false;
        }

        if (validate(email, emailPattern)) {
            json.addProperty(emailParameter, ok);
        } else {
            json.addProperty(emailParameter, wrong);
            successValidate = false;
        }

        if (validate(county, countryPattern)) {
            json.addProperty(countyParameter, ok);
        } else {
            json.addProperty(countyParameter, wrong);
            successValidate = false;
        }

        if (validate(city, cityPattern)) {
            json.addProperty(cityParameter, ok);
        } else {
            json.addProperty(cityParameter, wrong);
            successValidate = false;
        }

        if (validate(street, streetPattern)) {
            json.addProperty(streetParameter, ok);
        } else {
            json.addProperty(streetParameter, wrong);
            successValidate = false;
        }

        if (validate(home, homePattern)) {
            json.addProperty(homeParameter, ok);
        } else {
            json.addProperty(homeParameter, wrong);
            successValidate = false;
        }

        if (!successValidate) {
//            json.addProperty(successParameter, errorMessage);
            sendJSON(json, response);
            return;
        }

        boolean existsLogin = false;
        boolean existsEmail = false;

        try {
            InitialContext context = new InitialContext();
            UsersLocalHome homeUser = (UsersLocalHome) context.lookup("java:comp/env/Users");
            existsLogin = homeUser.isLoginExists(login);
            existsEmail = homeUser.isEmailExists(email);
        } catch (NamingException ex) {
            ex.printStackTrace();
        }

        if (existsLogin || existsEmail) {
            if (existsLogin) {
                json.addProperty(loginParameter, exists);
            }
            if (existsEmail) {
                json.addProperty(emailParameter, exists);
            }
//            json.addProperty(successParameter, errorMessage);
        } else {
            try {
                InitialContext context = new InitialContext();
                UsersLocalHome homeUser = (UsersLocalHome) context.lookup("java:comp/env/Users");
                Address address = new Address();
                ArrayList roles = new ArrayList();
                roles.add(UserRole.USER);
                address.setCountry(county);
                address.setCity(city);
                address.setStreet(street);
                address.setBuilding(home);
                address.setFlat(appartment);
                address.setLongitude(Double.valueOf(longitude));
                address.setLatitude(Double.valueOf(latitude));
                User user = new User();
                user.setAddress(address);
                user.setRoles(roles);
                user.setLogin(login);
                user.setPassword(password);
                user.setFirstName(fName);
                user.setLastName(lName);
                user.setEmail(email);
                homeUser.create(user);
                json.addProperty("success", "success");
//                System.err.println("Success registration");
            } catch (NamingException ex) {
                ex.printStackTrace();
            } catch (CreateException ex) {
                ex.printStackTrace();
            }
        }
        sendJSON(json, response);
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    private static boolean validate(String value, String pattern) {
        if (value == null) {
            return false;
        }
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(value);
        return m.matches() ? true : false;
    }

    private static void sendJSON(SimpleJSONObject json, HttpServletResponse response) {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.println(json);
            out.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            out.close();
        }
    }
}
